package com.waterfairy.particle;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.SurfaceHolder;

import androidx.annotation.NonNull;

import java.util.ArrayList;
import java.util.Random;

public class ObjectMoveEngine {

    private static final String TAG = "ObjectMoveEngine";
    private OnFreshListener onFreshListener;
    private FireworksSizeBean fireworksSizeBean = new FireworksSizeBean(0.6F, 0.5F);
    private ArrayList<ObjectBean> fireworksBeans = new ArrayList<>();
    //bitmap集合
    private ArrayList<Bitmap> bitmapList = new ArrayList<>();
    //复用数据
    private ArrayList<ObjectBean> reUseList = new ArrayList<>();
    private Random random = new Random();
    private Paint paint;
    private int configTop = 0;
    private int configBottom = 100;
    //密度系数
    private int configDensityCoefficient = 15;
    //速度
    private float configSpeedCoefficient = 100;
    private String info = "";
    private int height, width;
    private MyRunnable myRunnable = new MyRunnable(this);

    private Thread thread;
    private long perMillis = 16;

    public void setOnFreshListener(OnFreshListener onFreshListener) {
        this.onFreshListener = onFreshListener;
    }

    public OnFreshListener getOnFreshListener() {
        return onFreshListener;
    }

    public void setConfigBottom(int configBottom) {
        this.configBottom = configBottom;
    }

    public void setConfigCoefficient(int configDensityCoefficient) {
        this.configDensityCoefficient = configDensityCoefficient;
    }

    public void initPaint() {
        paint = new Paint();
        paint.setTextSize(40);
        paint.setColor(Color.RED);
        paint.setAntiAlias(true);
        paint.setStyle(Paint.Style.STROKE);
    }

    public void initSize(int width, int height) {
        this.width = Math.max(width, 0);
        this.height = Math.max(height, 0);
    }

    public void setBitmapList(ArrayList<Bitmap> bitmapList) {
        this.bitmapList = bitmapList;
    }

    public void stop() {
        myRunnable.stop = true;
    }


    public void onDraw(Canvas canvas) {
        if (canvas == null) return;
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < fireworksBeans.size(); i++) {
            fireworksBeans.get(i).onDraw(canvas);
        }
        Log.i(TAG, "onDraw: bitmap  :  " + (System.currentTimeMillis() - startTime));
    }


    public static class MyRunnable implements Runnable {
        private ObjectMoveEngine moveEngine;
        private boolean stop;
        private boolean transToMain;

        public MyRunnable(ObjectMoveEngine moveEngine) {
            this.moveEngine = moveEngine;
        }

        @Override
        public void run() {
            Looper.prepare();
            Handler handlerMain = new Handler(transToMain ? Looper.getMainLooper() : Looper.myLooper()) {
                @Override
                public void handleMessage(@NonNull Message msg) {
                    super.handleMessage(msg);
                    if (moveEngine.getOnFreshListener() != null)
                        moveEngine.getOnFreshListener().onFresh();
                }
            };

            Handler handler = new Handler() {
                @Override
                public void handleMessage(@NonNull Message msg) {
                    super.handleMessage(msg);
                    if (!stop) {
                        if (moveEngine.updateData()) {
                            handlerMain.sendEmptyMessage(0);
                        }
                        try {
                            Thread.sleep(moveEngine.perMillis);
                            sendEmptyMessage(0);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            };
            handler.sendEmptyMessage(0);
            Looper.loop();
        }

        public void transToMain(boolean transToMain) {
            this.transToMain = transToMain;
        }
    }


    public boolean updateData() {
        if (width == 0 || height == 0) return false;
        if (onFreshListener != null) {
            onFreshListener.onFresh();
        }
        long startTime = System.currentTimeMillis();
        int num = 0;
        //位移
        reUseList.clear();
        for (int i = 0; i < fireworksBeans.size(); i++) {
            ObjectBean fireworksBean = fireworksBeans.get(i);
            fireworksBean.update();
            RectF rect = fireworksBean.getRectF();
            //计算位移
            if (fireworksBean.enable && !(rect.bottom < configTop || rect.top > configBottom)) {
                num++;
            }
            //移出超出屏幕的数据
            if (rect.top > height) {
                fireworksBean.enable = false;
                reUseList.add(fireworksBean);
            }
        }

        info = "" + num + "--\n" + reUseList.size() + "--\n" + fireworksBeans.size();
        if (num < configDensityCoefficient) {
            int addNum = configDensityCoefficient - num;
            int reUseSize = reUseList.size();
            for (int i = 0; i < addNum; i++) {
                ObjectBean fireworksBean = null;
                if (i < reUseSize) {
                    fireworksBean = reUseList.get(i);
                } else {
                    fireworksBean = new ObjectBean();
                    fireworksBeans.add(fireworksBean);
                }
                float ratio;
                Bitmap bitmap;
                fireworksBean.init(bitmap = generateBitmap(),
                        generateCenterX(), (int) -(bitmap.getHeight() * (ratio = generateRatio() + 1) / 2), ratio, 0, generateSpeed());

            }
        }
        Log.i("TAG", "updateData: time:  " + (System.currentTimeMillis() - startTime));
        return true;
    }

    private int generateCenterX() {
        return random.nextInt(width);
    }


    private float generateSpeed() {
        return 100F + random.nextFloat() * configSpeedCoefficient;
    }

    /**
     * 元素的图片
     *
     * @return
     */
    private Bitmap generateBitmap() {
        if (bitmapList != null && bitmapList.size() > 0) {
            return bitmapList.get(random.nextInt(bitmapList.size() - 1));
        }
        return null;
    }

    /**
     * 放大比例
     *
     * @return
     */
    private float generateRatio() {
        float dRatio = fireworksSizeBean.getDRatio();
        return fireworksSizeBean.getMinRatio() + random.nextFloat() * dRatio;
    }

    public void start() {
        start(true);
    }


    public void start(boolean transToMain) {
        if (thread == null) {
            myRunnable.transToMain(transToMain);
            thread = new Thread(myRunnable, "calc_particle");
            thread.start();
        } else {
            myRunnable.stop = false;
        }
    }
}
